﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq.Expressions;

namespace GPS.DataAccessLayer
{
    public class GPS_GenericRepository<T> : IGPSGenericRepository<T> where T : class
    {
        public GPS_NVContext _db { get; set; }
        protected DbSet<T> _table = null;

        public GPS_GenericRepository()
        {
            _db = new GPS_NVContext();
            _table = _db.Set<T>();
        }

        public GPS_GenericRepository(GPS_NVContext _db)
        {
            this._db = _db;
            _table = _db.Set<T>();
        }

        // select all
        public IEnumerable<T> SelectAll()
        {
            return _table.ToList();            
        }

        // select by id
        public T SelectById(object id)
        {
            return _table.Find(id);
        }

        // select by id
        public T SelectById(object id1, object id2)
        {
            return _table.Find(id1, id2);
        }

        // select by id
        public T SelectById(object id1, object id2, object id3)
        {
            return _table.Find(id1, id2, id3);
        }

       
        // insert
        public void Insert(T obj)
        {
            _table.Add(obj);
        }

        // update
        public void Update(T obj)
        {
            _table.Attach(obj);
            _db.Entry(obj).State = EntityState.Modified;
        }

        // delete
        public void Delete(object id)
        {
            T existing = _table.Find(id);
            _table.Remove(existing);
        }

        // save
        public void Save()
        {
            _db.SaveChanges();
        }

        public void Dispose()
        {
            _db.Dispose();
        }


        public T GetOne<T>(Expression<Func<T, bool>> predicate) where T : class
        {
            return _db.Set<T>().Where(predicate).SingleOrDefault();
        }

        public IQueryable<T> GetTable<T>() where T : class
        {
            return _db.Set<T>().AsQueryable<T>();
        }
        public List<T> Filter<T>(Expression<Func<T, bool>> predicate) where T : class
        {
            return _db.Set<T>().Where(predicate).ToList();
        }

        public List<T> Filter<T>(Expression<Func<T, bool>> predicate, int pageNumber, int pageSize)
     where T : class
        {
            if (pageNumber < 1)
                throw new Exception("Page number is invalid.");
            return _db.Set<T>().Where(predicate).Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList();
        }
    }
}